{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "#官网论坛：xgboost baseline 0.85\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import xgboost\n",
    "\n",
    "PATH_TESTSET_PREDICTIONS = 'predict_tables/'\n",
    "FILENAME_TESTSET = 'original/testSet_predict_table.csv'\n",
    "FILENAME_TRAIN_AND_VALID = 'original/product_info_simple_final_train.csv'\n",
    "\n",
    "data = pd.read_csv(FILENAME_TESTSET)\n",
    "data2 = pd.read_csv(FILENAME_TRAIN_AND_VALID)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "from datetime import datetime\n",
    "\n",
    "base = int(datetime.strptime(str(20210104), \"%Y%m%d\").timestamp()) + 58320000\n",
    "change = lambda x: (int(datetime.strptime(str(x), \"%Y%m%d\").timestamp()) - base\n",
    "                    ) / 86400\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "#评价指标WMAPE\n",
    "def wmape_score( actuals,predictions):\n",
    "    actuals=list(actuals)\n",
    "    predictions=list(predictions)\n",
    "\n",
    "    len_predicitons = len(predictions)\n",
    "    wmape = 0.0\n",
    "    sum_real = sum([abs(i) for i in actuals])\n",
    "    \n",
    "    for i in range(len_predicitons):\n",
    "        pred = predictions[i]\n",
    "        real = actuals[i]\n",
    "        wmape += abs(pred - real)\n",
    "    #若分母为0，判断分子。若分子为0，输出0,；若分子不为0，输出100.\n",
    "    if sum_real==0:\n",
    "        if wmape==sum_real:\n",
    "            return 0\n",
    "        else:\n",
    "            return 100\n",
    "    wmape /= sum_real\n",
    "    \n",
    "    return wmape\n",
    "def compute_sum_diff_and_sum_real(actuals,predictions):\n",
    "    actuals=list(actuals)\n",
    "    predictions=list(predictions)\n",
    "    len_predicitons = len(predictions)\n",
    "    sum_diff = 0.0\n",
    "    sum_real = sum([abs(i) for i in actuals])\n",
    "    \n",
    "    for i in range(len_predicitons):\n",
    "        pred = predictions[i]\n",
    "        real = actuals[i]\n",
    "        sum_diff += abs(pred - real)\n",
    "    return sum_diff,sum_real"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "wmape on train set: 0.03606508879895152\n"
     ]
    }
   ],
   "source": [
    "models = {}\n",
    "models2 = {}\n",
    "models3 = {}\n",
    "\n",
    "sum_diff_train=0\n",
    "sum_real_train=0\n",
    "\n",
    "\n",
    "for i in data['product_pid'].unique():\n",
    "    X=data2[data2['product_pid']==i][\"transaction_date\"].apply(lambda x:change(x)).values.reshape(-1,1)\n",
    "    y=data2[data2['product_pid']==i][\"apply_amt\"]\n",
    "    y2=data2[data2['product_pid']==i][\"redeem_amt\"]\n",
    "    y3=data2[data2['product_pid']==i][\"net_in_amt\"]\n",
    "    models[i]=xgboost.XGBRegressor()\n",
    "    models[i].fit(X,y)\n",
    "\n",
    "    train_preds=models[i].predict(X)\n",
    "    this_sum_diff_train,this_sum_real_train=compute_sum_diff_and_sum_real(y,train_preds)\n",
    "    sum_diff_train+=this_sum_diff_train\n",
    "    sum_real_train+=this_sum_real_train\n",
    "\n",
    "    models2[i]=xgboost.XGBRegressor()\n",
    "    models2[i].fit(X,y2)\n",
    "\n",
    "    train_preds=models[i].predict(X)\n",
    "    this_sum_diff_train,this_sum_real_train=compute_sum_diff_and_sum_real(y,train_preds)\n",
    "    sum_diff_train+=this_sum_diff_train\n",
    "    sum_real_train+=this_sum_real_train\n",
    "\n",
    "    models3[i]=xgboost.XGBRegressor()\n",
    "    models3[i].fit(X,y3)\n",
    "\n",
    "    train_preds=models[i].predict(X)\n",
    "    this_sum_diff_train,this_sum_real_train=compute_sum_diff_and_sum_real(y,train_preds)\n",
    "    sum_diff_train+=this_sum_diff_train\n",
    "    sum_real_train+=this_sum_real_train\n",
    "\n",
    "wmape_train=sum_diff_train/sum_real_train\n",
    "print(f'wmape on train set: {wmape_train}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "#applyDirectRedeemDirectNetMixed，即论坛baseline的原做法。和applyDirectRedeemDirectNetDirect。\n",
    "for i in data[\"product_pid\"].unique():\n",
    "    X=data[data['product_pid']==i][\"transaction_date\"].apply(lambda x:change(x)).values.reshape(-1,1)\n",
    "    pre = models[i].predict(X)\n",
    "    pre2 = models2[i].predict(X)\n",
    "    pre3 = models3[i].predict(X)\n",
    "    data.loc[data['product_pid']==i,\"apply_amt_pred\"] = pre\n",
    "    data.loc[data['product_pid']==i,\"redeem_amt_pred\"] = pre2\n",
    "    data.loc[data['product_pid']==i,\"net_in_amt_pred\"] = pre3\n",
    "# #applyDirectRedeemDirectNetMixed\n",
    "# data[\"net_in_amt_pred\"] = (data[\"apply_amt_pred\"]-data[\"redeem_amt_pred\"])*0.5+data[\"net_in_amt_pred\"]*0.5\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "#applyDirectRedeemDirectNetDependent\n",
    "for i in data[\"product_pid\"].unique():\n",
    "    X=data[data['product_pid']==i][\"transaction_date\"].apply(lambda x:change(x)).values.reshape(-1,1)\n",
    "    pre = models[i].predict(X)\n",
    "    pre2 = models2[i].predict(X)\n",
    "\n",
    "    data.loc[data['product_pid']==i,\"apply_amt_pred\"] = pre\n",
    "    data.loc[data['product_pid']==i,\"redeem_amt_pred\"] = pre2\n",
    "data[\"net_in_amt_pred\"] = data[\"apply_amt_pred\"]-data[\"redeem_amt_pred\"]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# data.to_csv(PATH_TESTSET_PREDICTIONS+\"predict_table_forum_baseline_xgb.csv\",index=False)\n",
    "way_feature='numOfDaysFrom20210104'\n",
    "way_model='xgb'\n",
    "way_split='noValid'\n",
    "way_test='applyDirectRedeemDirectNetDirect'\n",
    "data.to_csv(PATH_TESTSET_PREDICTIONS+f\"predict_table_feature-{way_feature}_model-{way_model}_split-{way_split}_test-{way_test}.csv\",index=False,columns=['product_pid','transaction_date','apply_amt_pred','redeem_amt_pred','net_in_amt_pred'])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "AFAC2023ApplyAndRedeem_env",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.17"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
